package com.tfjybj.itoo.teach.provider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.dmsdbj.itoo.tool.base.entity.YearSemesterEntity;
import com.dmsdbj.itoo.tool.base.service.impl.BaseServicePlusImpl;
import com.dmsdbj.itoo.tool.constantutil.YearSemester;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tfjybj.itoo.teach.entity.CourseScheduleEntity;
import com.tfjybj.itoo.teach.entity.StudentTeachClassEntity;
import com.tfjybj.itoo.teach.model.*;
import com.tfjybj.itoo.teach.provider.dao.ClassDao;
import com.tfjybj.itoo.teach.provider.dao.CourseScheduleDao;
import com.tfjybj.itoo.teach.provider.dao.TrainingProgramsDao;
import com.tfjybj.itoo.teach.provider.service.CourseScheduleService;
import com.tfjybj.itoo.teach.provider.service.StudentTeachClassService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * CourseScheduleService接口实现类
 * ${base}表
 *
 * @author 田成荣
 * @version 2.0.0
 * @since 2.0.0 2018-11-08 19:34:10
 */
@Service("courseScheduleService")
public class CourseScheduleServiceImpl extends BaseServicePlusImpl<CourseScheduleDao, CourseScheduleEntity> implements CourseScheduleService {

    @Resource
    private ClassDao classDao;

    @Resource
    private TrainingProgramsDao trainingProgramsDao;
    //region 模板生成
    @Resource
    private CourseScheduleDao courseScheduleDao;

    @Resource
    private StudentTeachClassService studentTeachClassService;


    //endregion

    /* **********************************以下为非模板生成的内容********************************* */

    /**
     * 排课接口
     * @param arrangeCourseModel 排课实体
     * @return 排课是否成功
     * @author 杨晓慧
     * @since 2.0.0 2018-11-18 14:10:10
     */
    @Override
    public boolean insertArrangeCourseInfo(ArrangeCourseModel arrangeCourseModel) {
        List<CourseScheduleEntity> list = new ArrayList<>();
        List<String> classIds = arrangeCourseModel.getClassIds();
        String teachClassId = arrangeCourseModel.getTeachClassId();
        Date startDate = arrangeCourseModel.getStartDate();
        Date endDate = arrangeCourseModel.getEndDate();
        int lowLimit = arrangeCourseModel.getLowLimit();
        int topLimit = arrangeCourseModel.getTopLimit();
        String roomId = arrangeCourseModel.getRoomId();
        String courseId = arrangeCourseModel.getCourseId();
        String courseName = arrangeCourseModel.getCourseName();
        String teacherId = arrangeCourseModel.getTeacherId();
        String teacherName = arrangeCourseModel.getTeacherName();
        List<CourseScheduleModel> courseScheduleModelList = arrangeCourseModel.getCourseScheduleModelList();
        String semesterId = arrangeCourseModel.getSemesterId();


        if (!CollectionUtils.isEmpty(classIds)) {
            //1.当行政班集和为空时，即为必修课排课
            classIds.forEach(c -> {
                        courseScheduleModelList.forEach(x -> {
                                    CourseScheduleEntity courseScheduleEntity = new CourseScheduleEntity();
                                    BeanUtils.copyProperties(x, courseScheduleEntity);
                                    courseScheduleEntity.setClassId(c);
                                    courseScheduleEntity.setTeachClassId(teachClassId);
                                    courseScheduleEntity.setRoomId(roomId);
                                    courseScheduleEntity.setCourseId(courseId);
                                    courseScheduleEntity.setCourseName(courseName);
                                    courseScheduleEntity.setTeacherId(teacherId);
                                    courseScheduleEntity.setTeacherName(teacherName);
                                    courseScheduleEntity.setSemesterId(semesterId);
                                    courseScheduleEntity.setId(IdWorker.getIdStr());
                                    list.add(courseScheduleEntity);
                                }
                        );
                    }
            );
        } else {
            //2.当行政班集为空，不为具体行政班排课，为虚拟上课班排课
            courseScheduleModelList.forEach(x -> {
                        CourseScheduleEntity courseScheduleEntity = new CourseScheduleEntity();
                        BeanUtils.copyProperties(x, courseScheduleEntity);
                        courseScheduleEntity.setTeachClassId(teachClassId);
                        courseScheduleEntity.setRoomId(roomId);
                        courseScheduleEntity.setCourseId(courseId);
                        courseScheduleEntity.setCourseName(courseName);
                        courseScheduleEntity.setTeacherId(teacherId);
                        courseScheduleEntity.setTeacherName(teacherName);
                        courseScheduleEntity.setSemesterId(semesterId);
                        courseScheduleEntity.setEndDate(endDate);
                        courseScheduleEntity.setStartDate(startDate);
                        courseScheduleEntity.setLowLimit(lowLimit);
                        courseScheduleEntity.setTopLimit(topLimit);
                        courseScheduleEntity.setId(IdWorker.getIdStr());
                        list.add(courseScheduleEntity);
                    }
            );
        }

        //3.调用批量插入课表的接口
        return this.saveBatch(list);
    }

    /**
     * 检测冲突，返回被占用的时间段集和，返给前端--杨晓慧--2018年11月18日09:57:03     *
     * @param conditionMap 当前教室状态集和（教室id,起始周，学期id）
     * @return 返回已经被占用的时间段集和
     * @author 杨晓慧
     * @since 2.0.0 2018-11-18 14:10:10
     */
    @Override
    public List<CourseScheduleModel> queryArrangeCourseInfo(Map conditionMap) {
        List<CourseScheduleModel> listAllUsed = new ArrayList<>();

        //当roomId存在时 ，检测教室被占用情况
        if (conditionMap.containsKey("roomId")) {
            if (conditionMap.get("roomId")!="" && conditionMap.get("roomId")!=null) {
                List<CourseScheduleModel> listRoomUsed = courseScheduleDao.queryRoomUsedByWeekRoom(conditionMap);
                listAllUsed.addAll(listRoomUsed);
            }
        }

        //当教师id存在时检测教师已有授课安排情况
        if (conditionMap.containsKey("teacherId")) {
            if (conditionMap.get("teacherId")!="" && conditionMap.get("teacherId")!=null) {
                List<CourseScheduleModel> listTeacherUsed = courseScheduleDao.queryTeacherUsedByTeacherId(conditionMap);
                listAllUsed.addAll(listTeacherUsed);
            }
        }

        //当行政班集和不为空时候，检测行政班已有上课安排
        if (conditionMap.containsKey("classIds")) {
            if (conditionMap.get("classIds")!="" && conditionMap.get("classIds")!=null) {
                List<CourseScheduleModel> listClassUsed = courseScheduleDao.queryClassUsedByClassId(conditionMap);
                listAllUsed.addAll(listClassUsed);
            }
        }
        return listAllUsed;
    }


    /**
     * 根据班级_id查询的已排课课程和未排课程列表     *
     * @param classId 班级_id
     * @return courseMap
     * @author 杨晓慧
     * @since 2.0.0 2018-11-05 19:34:10
     */
    @Override
    public List<CourseIsArrangedModel> queryCourseAllByClassId(String classId) {

        //1. 根据班级获取专业id
        String professionId = classDao.queryProfessionIdByClassId(classId);
        //2.查询所有课程（根据专业id从培养计划取出该专业所有必修课程）
        List<TrainingProgramsModel> trainingProgramsList = trainingProgramsDao.queryCourseBySemProId("201820192", professionId);

        //初始化一个是否排课数组，存放已排和未排课程信息（最终的返回值）
        List<CourseIsArrangedModel> courseIsArrangedList = new ArrayList<>();
        //3.查询已排课程
        List<CourseScheduleModel> courseSchList = courseScheduleDao.queryCourseScheduleByClassId(classId);

        List<String> allCourseIdList = trainingProgramsList.stream().map(TrainingProgramsModel::getCourseId).collect(Collectors.toList());
        List<String> arrangedCourseIdList = courseSchList.stream().map(CourseScheduleModel::getCourseId).collect(Collectors.toList());

        //3.1 利用Set不重复特性,给已排课程集和去重（从课程表查出来的已排课程会有重复记录）
        Set set=new HashSet<String>();
        List<String> newArrangedCourseIdList= new ArrayList<>();
        set.addAll(arrangedCourseIdList);
        newArrangedCourseIdList.addAll(set);

        //4.两个集和求差集,得出所有待排课程
        allCourseIdList.removeAll(arrangedCourseIdList);

        //5.所有待排课程信息添加到返回数组
        allCourseIdList.forEach(n->{
            CourseIsArrangedModel courseArrangedOk = new CourseIsArrangedModel();
            Optional<TrainingProgramsModel> t= trainingProgramsList.stream().filter(a -> n.equals(a.getCourseId())).findFirst();

            courseArrangedOk.setCourseId(n);
            courseArrangedOk.setCourseName(t.get().getCourseName());
            courseArrangedOk.setIsArranged(false);
            courseIsArrangedList.add(courseArrangedOk);
        });

        //6.所有已排课程添加到返回数组中
        newArrangedCourseIdList.forEach(y->{
            CourseIsArrangedModel courseArrangedNo = new CourseIsArrangedModel();
            Optional<CourseScheduleModel> c= courseSchList.stream().filter(a -> y.equals(a.getCourseId())).findFirst();
            courseArrangedNo.setCourseId(c.orElse(null).getCourseId());
            courseArrangedNo.setCourseName(c.orElse(null).getCourseName());
            courseArrangedNo.setIsArranged(true);
            courseIsArrangedList.add(courseArrangedNo);
        });
        //7.返回已排和未排课程列表
         return courseIsArrangedList;
    }

    /**
     * 根据classId查询的课程表
     *
     * @param classId 学生ID
     * @return courseScheduleList
     * @author 田成荣
     * @since 2.0.0 2018-11-08 19:34:10
     */
    @Override
    public List<CourseScheduleModel> queryCourseScheduleByClassId(String classId) {
        return courseScheduleDao.queryCourseScheduleByClassId(classId);
    }

    /**
     * 根据teacherId查询的课程表
     *
     * @param teacherId 教师ID
     * @return courseScheduleList
     * @author 田成荣
     * @since 2.0.0 2018-11-08 19:34:10
     */
    @Override
    public List<CourseScheduleModel> queryCourseScheduleByTeacherId(String teacherId) {
        return courseScheduleDao.queryCourseScheduleByTeacherId(teacherId);
    }

    /**
     * 根据上课班id集合来查询课程id集和
     *
     * @param teachClassList 上课班id集和
     * @return 课程id集和
     * @author 杨晓慧
     * @since 2.0.0 2018-11-08 20:35:10
     */
    @Override
    public List<String> queryCourseIdsByTeachClassIds(List<String> teachClassList) {
        return courseScheduleDao.queryCourseIdsByTeachClassIds(teachClassList);
    }

    /**
     * 根据id集合来查询课程表集和
     *
     * @param ids 课程id集和
     * @return 课程表集和_listCourseScheduleModel
     * @author 田成荣
     * @since 2.0.0 2018-11-08 20:35:10
     */
    @Override
    public List<CourseScheduleModel> queryCourseScheduleByIds(List<String> ids) {
        return courseScheduleDao.queryCourseScheduleByIds(ids);
    }


    /**
     * 根据ID查找单个实体
     *
     * @param pageNo   页码
     * @param pageSize 每页条数
     * @return 实体集合
     * @author 杨晓慧
     * @since 2.0.0 2018-11-20 10:35:10
     */
    @Override
    public PageInfo<CourseScheduleModel> queryPageCourseAll(int pageNo, int pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        return new PageInfo<>(courseScheduleDao.queryAllCourseSchedule());
    }


    /**
     * 高级搜索条件查询课表信息
     * @param strLikeMap 教师，班级，课程信息Map
     * @return 课程表信息列表
     * @author 杨晓慧
     * @since 2.0.0 2018年11月27日11:00:25
     */
    @Override
    public PageInfo<CourseScheduleModel> queryScheduleByStrLike(Map strLikeMap, int pageNo, int pageSize) {

        //若courseName为空时，前端传过来的strLikeMap中不包含courseName，所以这里传入空值，不影响mapper
        //teacherName与className同上
        if (!strLikeMap.containsKey("courseName")) {
            strLikeMap.put("courseName","");
        }
        if (!strLikeMap.containsKey("teacherName")) {
            strLikeMap.put("teacherName","");
        }
        if (!strLikeMap.containsKey("className")) {
            strLikeMap.put("className","");
        }
        PageHelper.startPage(pageNo, pageSize);
        return new PageInfo<CourseScheduleModel>(courseScheduleDao.queryScheduleByStrLike(strLikeMap));
    }

    /**
     * 根据课程id来查询课表信息
     *
     * @param courseId 课程id
     * @return 课程表信息
     * @author 杨晓慧
     * @since 2.0.0 2018年11月20日15:43:24
     */
    @Override
    public List<CourseScheduleModel> queryScheduleByCourseId(String courseId) {
        return courseScheduleDao.queryScheduleByCourseId(courseId);
    }


    /**
     * 根据学院名称和专业名称查询行政班信息
     *
     * @param strLike 模糊查询字段
     * @return 行政班列表
     * @author 杨晓慧
     * @since 2.0.0 2018年11月22日14:43:20
     */
    @Override
    public List<ClassModel> queryClassByAcmOrPfs(String strLike, String academyId) {
        if (strLike == null || "undefined".equals(strLike)) {
            strLike = "";
        }
        if (academyId == null || "undefined".equals(academyId)) {
            academyId = "";
        }

        // 利用工具类获取在校年级集和
        List<YearSemesterEntity> yearList = YearSemester.getYearList(-3, 0);

        // 过滤到所有年级放到数组中
        List<String> yearCode = yearList.stream().map(YearSemesterEntity::getCode).collect(Collectors.toList());

        // 根据模糊查询信息和年级信息查询符合条件班级
        return courseScheduleDao.queryClassByAcmOrPfs(strLike,academyId,yearCode);
    }

    /**
     * 根据学生id查询所在的上课班id集和
     * @param studentId 学生id
     * @return 所在的上课班id集和
     * @author 杨晓慧
     * @since 2.0.0 2018年10月22日18:43:20
     */
    @Override
    public List<String> queryTechClassIdByStudentId(String studentId) {

        QueryWrapper<StudentTeachClassEntity> studentTeachClassEntityQueryWrapper=new QueryWrapper<>();

        //根据学生id查出该学生所在的所有上课班（选修课上课班）
        studentTeachClassEntityQueryWrapper.eq("student_id",studentId);
        List<StudentTeachClassEntity> studentTeachClassEntityList = studentTeachClassService.list(studentTeachClassEntityQueryWrapper);

        return studentTeachClassEntityList.stream().map(StudentTeachClassEntity::getTeachClassId).collect(Collectors.toList());

    }

    /**
     * 根据上课班id集和查询课程表信息
     * @param teachClassIds 上课班id集和
     * @return 课程表信息列表
     * @author 杨晓慧
     * @since 2.0.0 2018-11-28 15:45:08
     */
    @Override
    public List<CourseScheduleModel> queryCourseScheduleByTeachClassIds(List<String> teachClassIds) {
        return courseScheduleDao.queryCourseScheduleByTeachClassIds(teachClassIds);
    }


    /**
     * 根据教室id查询该班级的课表情况
     * @param RoomId 教室id
     * @return 返回该教室课表清空
     * @author 杨晓慧
     * @since 2.0.0 2018年12月3日15:40:30
     */
    @Override
    public List<CourseScheduleModel> queryCourseScheduleByRoomId(String RoomId) {
        return courseScheduleDao.queryCourseScheduleByRoomId(RoomId);
    }

    /**
     * 根据班级_id模糊查询courseSchedule
     *
     * @param classId  班级_id
     * @param pageNo   页码
     * @param pageSize 页数
     * @return 模糊查询的courseSchedule
     * @author 智雪艳
     * @since 2.0.0 2019-05-30 10:35:56
     */
    @Override
    public PageInfo<CourseScheduleEntity> queryCourseScheduleByLikeClassId(String classId, Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        return new PageInfo<>(courseScheduleDao.queryCourseScheduleByLikeClassId(classId));
    }

    /**
     * 根据id查找CourseSchedule
     *
     * @param courseId 主键courseId
     * @author 智雪艳
     * @since 2.0.0 2019-05-30 10:35:56
     */
    @Override
    public String findByCourseId(String courseId) {
        CourseScheduleEntity courseScheduleEntity=courseScheduleDao.findByCourseId(courseId);
        if (courseScheduleEntity==null){
            return "";
        }else {
            return courseScheduleEntity.getCourseName();
        }
    }

    /**
     * 无参查询查找CourseSchedule
     *
     * @return courseScheduleEntity
     * @author 智雪艳
     * @since 2.0.0 2019-05-30 10:35:56
     */
    @Override
    public List<CourseScheduleEntity> queryCourse() {
        return courseScheduleDao.queryCourse();
    }

}
